<template>
    <div class="longListBox" ref="longListBox" @scroll="onScroll">
        <div :style="{ height: `${totalHeight}px` }" class="container">
            <div class="item" :style="{ transform: `translateY(${item.position}px)` }" v-for="item in pool"
                :key="item.item.id">
                <slot :item="item.item" name="shuai"></slot>
            </div>
        </div>
    </div>
</template>

<script setup>
import { computed, ref, onMounted, defineProps } from "vue"
const longListBox = ref(null)

const props = defineProps({
    items: {
        type: Array,
        default: []
    },
    itemSize: {
        type: Number,
        default: 10
    },
    preLoad: {
        type: Number,
        default: 0
    },
    nextLoad: {
        type: Number,
        default: 10
    }
})
const pool = ref([])
let timer = null

function setPool(){
    const $longListBox = longListBox.value
    let scollTop = $longListBox.scrollTop
    let height = $longListBox.clientHeight
    let startIndex, endIndex, startPosition;
    startIndex = Math.floor(scollTop / props.itemSize) - props.preLoad
    if (startIndex < 0) {
        startIndex = 0
    }
    endIndex = Math.floor((scollTop + height) / props.itemSize) + props.nextLoad
    startPosition = startIndex * props.itemSize
    pool.value = props.items.slice(startIndex, endIndex).map((item, index) => ({
        item,
        position: startPosition + index * props.itemSize
    }))
}

function onScroll(){
    debounce(setPool)
}

function debounce(fn){
    if (timer) {
        return
    }
    timer = setTimeout(() => {
        fn()
        clearTimeout(timer)
        timer = null
    }, 100)
}
const totalHeight = computed( () => props.itemSize * props.items.length )
onMounted(() => {
    setPool()
})
</script>
<style lang="scss">
.longListBox {
    position: relative;
    overflow: auto;
    height: 100vh;

    .container {
        position: relative;

        .item {
            position: absolute;
        }
    }
}
</style>